<?php
/**
 * DES加解密
 * @author Thor.Wang
 * Date: 14-7-25 上午11:11
 */
class DESService extends BaseService
{
    private $aReplace = array(
        '+' => '**',
        '=' => '!!',
    );

    /**
     * @var DESService
     */
    private static $self = NULL;

    static public function instance()
    {
        if (self::$self == NULL) {
            self::$self = new self;
        }

        return self::$self;
    }

    private $key;
    private $iv; //偏移量

    public function __construct()
    {
        $des_key = Config::get('external_api.host_agent_des_key');
        $des_iv  = Config::get('external_api.host_agent_des_iv');

        $this->key = substr($des_key, 0, 8);
        $this->iv  = $des_iv;
    }

    //加密
    public function encode($str)
    {
        $size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC);
        $str  = $this->pkcs5Pad($str, $size);

        $data = mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_ENCRYPT, $this->iv);
        $data = base64_encode($data);
        $data = str_replace(array_keys($this->aReplace),array_values($this->aReplace),$data);
        return $data;
    }

    //解密
    public function decode($str)
    {
        $str = str_replace(array_values($this->aReplace),array_keys($this->aReplace),$str);
        $str = base64_decode($str);
        $str = mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_DECRYPT, $this->iv);
        $str = $this->pkcs5Unpad($str);

        return $str;
    }

    private function pkcs5Pad($text, $blocksize)
    {
        $pad = $blocksize - (strlen($text) % $blocksize);

        return $text . str_repeat(chr($pad), $pad);
    }

    private function pkcs5Unpad($text)
    {
        $pad = ord($text{strlen($text) - 1});
        if ($pad > strlen($text))
            return FALSE;
        if (strspn($text, chr($pad), strlen($text) - $pad) != $pad)
            return FALSE;

        return substr($text, 0, -1 * $pad);
    }

    /**
     * 将md5字符串转化为10进制
     * @param $str
     * @return string
     */
    public function md5ToDec($str)
    {
        $str_code = '';
        for($i = 0;$i<16;$i++)
        {
            $str_code .= (string)floor(hexdec($str[$i]) / 16 * 10);
        }
        return $str_code;
    }
}